/*****************************************************************
Copyright (c) 2008 Smart Mai (smardio@gmail.com).
All rights reserved. This program and the accompanying materials
are made available under the terms of the GNU Public License v2.0
which accompanies this distribution, and is available at
http://www.gnu.org/licenses/old-licenses/gpl-2.0.html

Contributors:
    Smart Mai (smardio@gmail.com) - initial API and implementation
******************************************************************/
package com.smartdio.example.util;

import java.io.*;
import java.net.*;
/**
 * 
 * @author 麦廷琮
 *
 * 用于文件操作的一系列静态方法.
 */
public class FileUtil {
  /**
   * 从文件整个路径中获取文件名，就是最后一段的名字。
   * @param filePath
   * @return
   */
  static public String getShortFileName(String filePath) {
    filePath = filePath.replaceAll("\\\\", "/");
    String[] names = filePath.split("/");
    return names[names.length - 1];
  }

  /**
   * 删除指定的文件
   * @param filePath
   * @return
   */
  static public boolean deleteFile(String filePath) {
    File file = new File(filePath);
    return file.delete();
  }

  /**
   * 把数据保存到文件中。
   * @param filePath
   * @param data
   * @throws IOException
   */
  static public void saveFile(String filePath, byte[] data) throws IOException {
    File file = new File(filePath);
    if (!file.exists()) {
      if (!file.createNewFile()) {
        throw new IOException("can't create " + filePath);
      }
    }

    FileOutputStream output = new FileOutputStream(file, false);
    output.write(data);
    output.close();
  }

  /**
   * 从网上资源复制一个文件保存到本地磁盘中。
   * @param url  网上资源的URL
   * @param fileName  本地文件名
   * @throws java.lang.Exception
   */
  static public void copyFile(String url, String fileName) throws Exception {
    byte[] b = readFile(url);
    saveFile(fileName, b);
  }

  /**
   * 读取网上资源的文件
   * @param urlStr  url
   * @return  返回读取的byte
   * @throws java.lang.Exception
   */
  static public byte[] readFile(String urlStr) throws IOException {
    URL url = new URL(urlStr);
    return readFile(url);
  }
  
  static public byte[] readFile(URL url)throws IOException{
	  // con.setUseCaches(true);
	    //con.connect();
	    /** @todo 对于内存的缓冲还没有细致研究 */
	    InputStream stream = url.openConnection().getInputStream();
	    int length = stream.available();
	    //length = 655360;
	    byte[] b = new byte[length];
	    int i = 0;
	    int of = 0;
	    while (i >= 0) {
	      i = stream.read(b, of, length - of);
	      if (of == length) {
	        break;
	      }
	      of = of + i;
	    }
	    length = of + 1;
	    byte[] result = new byte[b.length];
	    for (i = 0; i < result.length; i++) {
	      result[i] = b[i];
	    }
	    return result;
  }
  
  /**
   * 读取文本文件,采用自动判断编码.如果在文本中无法获取编码信息,则采用系统默认的编码.
   * @param filePath   文本文件的路径
   * @return   返回文本内容
   * @throws IOException   
   */
	static public String readTextFile(String filePath) throws IOException {
		return readTextFile(filePath ,null);
	}

  /**
        * 读取文本文件
        * 2003-12-10 作出修改,增加编码的自动检测.
        * 如果指定encode为null ,则自动进行编码判断.根据字符串中包含的编码来读取文件内容.
        * @param filePath  文件的路径。
        * @param encode  文件的编码，如果是空则自动选择编码
        * @return  返回文件的内容
        * @throws IOException
        */
  static public String readTextFile(String filePath, String encode) throws IOException {
    File file = new File(filePath);
    if (!file.exists()) {
      throw new IOException("no such file " + filePath);
    }

    FileInputStream inStream = new FileInputStream(file);
    /*旧的读取方式
    BufferedReader in;
    if (encode != null) {
      in = new BufferedReader(new InputStreamReader(inStream, encode));
    } else {
      in = new BufferedReader(new InputStreamReader(inStream));
    }
    StringBuffer content = new StringBuffer(1024);
    while (true) {
      String str = in.readLine();
    
      if (str == null) {
        return content.toString();
      }
      content.append(str).append("\n");
    }
    */
    int length = inStream.available();
    //length = 655360;
    byte[] b = new byte[length];
    int i = 0;
    int of = 0;
    while (i >= 0) {
      i = inStream.read(b, of, length - of);
      if (of == length) {
        break;
      }
      of = of + i;
    }
    //获取编码
    if(encode==null)
    encode = getCharSet(b);
    if (encode != null) {

    } else { //如果设定了编码,按照编码进行构造

    }
    //设定编码并返回
    return encode == null ? new String(b).trim() : new String(b, encode).trim();
  }

  /**
   * 获取某段未进行编码的文本内容的编码.
   * 判断编码的算法很简单,就是判断在内容里面有没有 charset= 这段文字,然后获取编码的描述.
   * @param bytes 文本内容
   * @return  编码的名称,如果无法获取编码的名称,返回null
   */
  static public String getCharSet(byte[] bytes) {
    String charset = null;
    for (int i = 0; i < bytes.length; i++) {
    	if(bytes[i]=='c'){
    		charset=charSet(bytes,i);
    		if(charset!=null)return charset;
    	}
    }
    return charset;
  }

  static protected String charSet(byte[] bytes, int p) {
    //charset=
    String charset = null;
    boolean boolResult = true;
    if (p > bytes.length - 9) {
      return null;
    }
    boolResult = bytes[p] == 'c' || bytes[p] == 'C' ? boolResult : false;
    boolResult = bytes[p + 1] == 'h' || bytes[p + 1] == 'H' ? boolResult : false;
    boolResult = bytes[p + 2] == 'a' || bytes[p + 2] == 'A' ? boolResult : false;
    boolResult = bytes[p + 3] == 'r' || bytes[p + 3] == 'R' ? boolResult : false;
    boolResult = bytes[p + 4] == 's' || bytes[p + 4] == 'S' ? boolResult : false;
    boolResult = bytes[p + 5] == 'e' || bytes[p + 5] == 'E' ? boolResult : false;
    boolResult = bytes[p + 6] == 't' || bytes[p + 6] == 'T' ? boolResult : false;
    boolResult = bytes[p + 7] == '=' ? boolResult : false;
    if (boolResult) {
    	//获取等号后面的内容
    	
    	int start=p+8;
    	if(bytes[start]=='\'' || bytes[start]=='"')start++;
			int end =start;
    	for(int i=start;i<bytes.length;i++){
    		if(bytes[i]==' ' || bytes[i]=='\'' || bytes[i]=='"'){
    			end = i ;
    			 break;
    		}
    	}
    	try{
				charset = new String(bytes,start,end-start,"UTF-8");
				if(charset.length()==0)return null;
    	}catch(Exception e){
    		return null;
    	}
    	
    }
    return charset;

  }

  /**	
  * 写文本数据文件的方法。
  * @param fileName  注意文件名，是完整的路径 ；
  * @param data  文件数据
  * @param encode 保存文件时采用的的编码，建议采用 UTF-8
  * @throws IOException
  */
  static public void saveTextFile(String filePath, String data, String encode) throws IOException {
    File file = new File(filePath);
    if (!file.exists()) {
      if (!file.createNewFile()) {
        throw new IOException("can't create " + filePath);
      }
    }

    FileOutputStream output = new FileOutputStream(file, false);
    BufferedWriter awriter;
    awriter = new BufferedWriter(new OutputStreamWriter(output, encode));
    awriter.write(data);
    awriter.flush();

  }

  static public void moveFile(String sourceFile, String targetFile) throws IOException {
    File source = new File(sourceFile);
    File target = new File(targetFile);
    source.renameTo(target);
  }
  
  /**
   * 从一个输入流中读取文本
   *
   */
  static public String readTextStream(InputStream inStream, String encode)throws IOException{
		int length = inStream.available();
			 //length = 655360;
			 byte[] b = new byte[length];
			 int i = 0;
			 int of = 0;
			 while (i >= 0) {
				 i = inStream.read(b, of, length - of);
				 if (of == length) {
					 break;
				 }
				 of = of + i;
			 }
			 //获取编码
			 encode = getCharSet(b);
			 if (encode != null) {

			 } else { //如果设定了编码,按照编码进行构造

			 }
			 //设定编码并返回
			 return encode == null ? new String(b).trim() : new String(b, encode).trim();
  	
  }
  
  static public String readTextStream(InputStream inStream)throws IOException{
  	return readTextStream(inStream,null);
  }

}